﻿using System;
using System.Linq;
namespace System.Data.Services.Providers
{
    /// <summary>
    /// This interface declares the methods required to support the $expand and $select
    /// query options for a WCF Data Service. This interface is a superset
    /// of <see cref="T:System.Data.Services.IExpandProvider" /> interface and adds support for paging
    /// in the expanded results and projections.
    /// </summary>
    internal interface IProjectionProvider
    {
        /// <summary>Applies expansions and projections to the specified <paramref name="source" />.</summary>
        /// <param name="source"><see cref="T:System.Linq.IQueryable" /> object to expand and apply projections to.</param>
        /// <param name="rootProjectionNode">The root node of the tree which describes
        ///     the projections and expansions to be applied to the <paramref name="source" />.</param>
        /// <param name="epmRelevantForCurrentFormat">Determine if the current Response format needs epm values.</param>
        /// <returns>
        /// An <see cref="T:System.Linq.IQueryable" /> object, with the results including 
        /// the expansions and projections specified in <paramref name="rootProjectionNode" />. 
        /// </returns>
        /// <remarks>
        /// The returned <see cref="T:System.Linq.IQueryable" /> may implement the <see cref="T:System.Data.Services.IExpandedResult" /> interface 
        /// to provide enumerable objects for the expansions; otherwise, the expanded
        /// information is expected to be found directly in the enumerated objects. If paging is 
        /// requested by providing a non-empty list in <paramref name="rootProjectionNode" />.OrderingInfo then
        /// it is expected that the topmost <see cref="T:System.Data.Services.IExpandedResult" /> would have a $skiptoken property 
        /// which will be an <see cref="T:System.Data.Services.IExpandedResult" /> in itself and each of it's sub-properties will
        /// be named SkipTokenPropertyXX where XX represents numbers in increasing order starting from 0. Each of 
        /// SkipTokenPropertyXX properties will be used to generated the $skiptoken to support paging.
        /// If projections are required, the provider may choose to return <see cref="T:System.Linq.IQueryable" />
        /// which returns instances of <see cref="T:System.Data.Services.IProjectedResult" />. In that case property values are determined
        /// by calling the <see cref="M:System.Data.Services.IProjectedResult.GetProjectedPropertyValue(System.String)" /> method instead of
        /// accessing properties of the returned object directly.
        /// If both expansion and projections are required, the provider may choose to return <see cref="T:System.Linq.IQueryable" />
        /// of <see cref="T:System.Data.Services.IExpandedResult" /> which in turn returns <see cref="T:System.Data.Services.IProjectedResult" /> from its
        /// <see cref="P:System.Data.Services.IExpandedResult.ExpandedElement" /> property.
        /// </remarks>
        IQueryable ApplyProjections(IQueryable source, RootProjectionNode rootProjectionNode, bool epmRelevantForCurrentFormat);
    }
}